﻿/**
 * 串口驱动
 */
#pragma once

#include <vector>
#include <memory>

#include "xuartps.h"
#include "xscugic.h"

/**
 * 串口驱动
 */
class ZUartDriver {
public:
  /**
   * 构造函数
   * @param UART_DEVICE_ID 串口设备ID
   * @param INTC_DEVICE_ID 中断ID
   * @param UART_INT_IRQ_ID 串口中断ID
   * @param dataDeal 数据接收的中断函数
   * @param baudRate 波特率
   * @param triggerLevel 中断响应的字节数(当收到这么多字节时触发,范围1~63)
   * @param priority 中断的优先级,数值越低则优先度更高(0/8/16/32...248)
   */
  explicit ZUartDriver(
      uint32_t UART_DEVICE_ID,
      uint32_t INTC_DEVICE_ID,
      uint32_t UART_INT_IRQ_ID,
      void (*dataDeal)(void *) = nullptr,
      uint32_t baudRate = 115200,
      uint8_t triggerLevel = 32,
      uint8_t priority = 16
      );

  /**
   * 写入数据
   * @param data 待写入的数据
   * @return 写入的字符数
   */
  void write(const std::vector<uint8_t> &data) const;

  /**
   * 写入数据
   * @param data 待写入的数据指针
   * @param size 带写入的数据长度
   */
  void write(uint8_t *data, uint32_t size) const;

private:
  /**
   * 初始化
   */
  void initialize();

  /**
   * 初始化串口设备
   */
  void initUartDevice();

  /**
   * 初始化中断
   */
  void initInterrupts();

  /**
   * 中断处理函数,接收数据并进行处理,这里是个示例参考
   */
  static void interruptHandler(void *call_back_ref);

private:
  // 串口设备ID
  uint32_t UART_DEVICE_ID_;
  // 中断ID
  uint32_t INTC_DEVICE_ID_;
  // 串口中断ID
  uint32_t UART_INT_IRQ_ID_;

  // 接收到的数据处理函数
  void (*dataDeal_)(void *);
  // 波特率
  uint32_t baudRate_;
  // 中断响应的字节数(当收到这么多字节时触发,范围1~63)
  uint8_t triggerLevel_;
  // 中断的优先级,数值越低则优先度更高(0/8/16/32...248)
  uint8_t priority_;
  // 串口的handle
  std::shared_ptr<XUartPs> uartPs_;
  // 中断控制器
  std::shared_ptr<XScuGic> intc_;
};